home *** CD-ROM | disk | FTP | other *** search
- #ifdef UNIX
- #include <stdio.h>
- #include <time.h>
- #include <sys/stat.h>
- #include "dirutil.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: glob.c,v 1.10 1997/08/19 01:19:22 root Exp root $";
- #endif
-
-
- #ifdef __cplusplus
- extern "C" {
- #endif
- extern uid_t geteuid (void);
- extern gid_t getegid (void);
- #ifdef __cplusplus
- }
- #endif
-
- /*
- * Second approximation of glob routine for JNOS/Linux
- */
-
- static int ff1(const char *, const char *, const char *, struct ffblk *, int);
-
- static char *
- __ff_cat(const char *pfx, const char *sfx)
- {
- static char buf[1024];
-
- buf[0] = '\0';
- if (pfx && *pfx)
- strcat(buf, pfx);
- if (pfx && *pfx && sfx && *sfx && (*pfx != '/' || pfx[1] != '\0'))
- strcat(buf, "/");
- if (sfx && *sfx)
- strcat(buf, sfx);
- return buf;
- }
-
- int
- findnext(struct ffblk *ff)
- {
- struct stat sb;
- char *path;
- int m;
-
- /* special-case literal: if there's no pattern, just close the ff */
- if (!ff->ff_pat || !ff->ff_dir)
- return -1;
- for (;;)
- {
- while ((ff->ff_cur = readdir(ff->ff_dir)) != 0 &&
- wildmat(ff->ff_cur->d_name, ff->ff_pat, 0) == 0)
- ;
- if (!ff->ff_cur)
- {
- (void) closedir(ff->ff_dir);
- ff->ff_dir = 0;
- j_free(ff->ff_pat);
- j_free(ff->ff_pfx);
- return -1;
- }
- path = strdup(__ff_cat(ff->ff_pfx, ff->ff_cur->d_name));
- if ((*ff->ff_cur->d_name == '.' && !(ff->ff_sattr & FA_HIDDEN)) ||
- stat(path, &sb) == -1 ||
- (!(ff->ff_sattr & FA_DIREC) && S_ISDIR(sb.st_mode)) ||
- (!S_ISREG(sb.st_mode) && !(ff->ff_sattr & FA_SYSTEM) &&
- !(ff->ff_sattr & FA_HIDDEN)))
- {
- j_free(path);
- continue;
- }
- j_free(path);
- if (geteuid() == sb.st_uid)
- m = 0700;
- else if (getegid() == sb.st_gid)
- m = 0070;
- else
- m = 0007;
- if (!(sb.st_mode & m) && !(ff->ff_sattr & FA_SYSTEM))
- continue;
- ff->ff_ftime = *localtime(&sb.st_mtime);
- ff->ff_fsize = sb.st_size;
- if (S_ISDIR(sb.st_mode))
- ff->ff_attrib = FA_DIREC;
- else if (!S_ISREG(sb.st_mode) || !(sb.st_mode & m))
- ff->ff_attrib = FA_SYSTEM | FA_HIDDEN;
- else
- ff->ff_attrib = FA_NORMAL;
- if (*ff->ff_cur->d_name == '.')
- ff->ff_attrib |= FA_HIDDEN;
- if (!(sb.st_mode & m & 0222))
- ff->ff_attrib |= FA_RDONLY;
- strncpy(ff->ff_name, ff->ff_cur->d_name, sizeof(ff->ff_name));
- return 0;
- }
- }
-
- static int
- ff1(const char *prefix, const char *thedir, const char *pat, struct ffblk *ff, int attr)
- {
- char *pp, *cp, *ep, *xp;
- char const *bp;
- struct stat sb;
- int m;
-
- ff->ff_pfx = strdup(__ff_cat(prefix, thedir));
- ff->ff_pat = 0;
- ff->ff_dir = 0;
- ff->ff_cur = 0;
- ff->ff_name[0] = '\0';
- ff->ff_sattr = attr;
- cp = ep = pp = strdup(pat);
- xp = 0;
- bp = "";
- for (; *cp; cp = ep)
- {
- while (*ep && *ep != '/') /* extract next component */
- {
- if (*ep == '?' || *ep == '*' || *ep == '[')
- xp = ep; /* record presence of wildcard characters */
- ep++;
- }
- if (*ep)
- *ep++ = '\0';
- if (xp) /* if we got a wildcard, abort */
- break;
- if (!*cp || strcmp(cp, ".") == 0) /* prune null components */
- continue;
- xp = ff->ff_pfx; /* append component to prefix */
- ff->ff_pfx = strdup(__ff_cat(xp, cp));
- j_free(xp);
- xp = 0;
- bp = cp;
- }
- if (!xp) /* no wildcards; just return it */
- {
- strncpy(ff->ff_name, bp, sizeof(ff->ff_name));
- if ((*bp == '.' && !(attr & FA_HIDDEN)) ||
- stat(ff->ff_pfx, &sb) == -1 ||
- (!(attr & FA_DIREC) && S_ISDIR(sb.st_mode)) ||
- (!S_ISREG(sb.st_mode) && !(attr & FA_SYSTEM) &&
- !(attr & FA_HIDDEN)))
- {
- j_free(pp);
- j_free(ff->ff_pfx);
- return -1;
- }
- /* unreadable files are system files */
- /* don't check for root: if you run nos as root you're dead anyway */
- if (geteuid() == sb.st_uid)
- m = 0700;
- else if (getegid() == sb.st_gid) /* WARNING: ignores group vec */
- m = 0070;
- else
- m = 0007;
- if (!(attr & FA_SYSTEM) && !(sb.st_mode & m))
- {
- j_free(ff->ff_pfx);
- j_free(pp);
- return -1;
- }
- ff->ff_ftime = *localtime(&sb.st_mtime);
- ff->ff_fsize = sb.st_size;
- if (S_ISDIR(sb.st_mode))
- ff->ff_attrib = FA_DIREC;
- else if (!S_ISREG(sb.st_mode) || !(sb.st_mode & m))
- ff->ff_attrib = FA_SYSTEM | FA_HIDDEN;
- else
- ff->ff_attrib = FA_NORMAL;
- if (*bp == '.')
- ff->ff_attrib |= FA_HIDDEN;
- if (!(sb.st_mode & m & 0222))
- ff->ff_attrib |= FA_RDONLY;
- j_free(pp);
- j_free(ff->ff_pfx);
- ff->ff_pfx = 0;
- return 0;
- }
- if (*ep) /* no subdirs this version */
- {
- j_free(ff->ff_pfx);
- j_free(pp);
- return -1;
- }
- ff->ff_pat = strdup(cp); /* the wildcarded component */
- j_free(pp);
- if ((ff->ff_dir = opendir(*ff->ff_pfx? ff->ff_pfx: ".")) == (DIR *)0)
- {
- j_free(ff->ff_pat);
- j_free(ff->ff_pfx);
- return -1;
- }
- return findnext(ff);
- }
-
- int
- findfirst(const char *pat, struct ffblk *ff, int attr)
- {
- return ff1((*pat == '/'? "/": ""), "", (*pat == '/'? pat + 1: pat),
- ff, attr);
- }
-
- #if 0
- void
- findlast(struct ffblk *ff)
- {
- if (!ff->ff_dir)
- return;
- (void) closedir(ff->ff_dir);
- j_free(ff->ff_pat);
- j_free(ff->ff_pfx);
- }
- #endif
-
- #endif /* UNIX */
-